package brau.util;

import java.math.BigDecimal;
import java.sql.BatchUpdateException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import javax.faces.model.SelectItem;
import javax.validation.ConstraintViolationException;


public class Utilitarios {

	public Utilitarios() {
	}

	
	public static String prepararLogradouroParaPesqGMap(String logradouro) {
		
		String retorno = "";
		
		String[] logrArray = logradouro.split(" ");
		for (int i = 0; i < logrArray.length; i++) if (logrArray[i].length() >= 3) retorno += logrArray[i] + "%20";
		
		return retorno.substring(0, retorno.length()-3);
	}
	
	
	public static Double calcularDistancia(Double latitude1, Double longitude1, Double latitude2, Double longitude2, String unit) {

		Double theta;
		Double dist;
		theta = longitude1 - longitude2;
		dist = 	( Math.sin(Math.toRadians(latitude1)) * Math.sin(Math.toRadians(latitude2)) ) + 
				( Math.cos(Math.toRadians(latitude1)) * Math.cos(Math.toRadians(latitude2)) * Math.cos(Math.toRadians(theta)) );

//		System.out.println("dist = " + dist );
		
		dist = Math.acos(dist);
		dist = Math.toDegrees(dist);
		
//		System.out.println("dist = " + dist );

		Double distance = dist * 60 * 1.1515;
		
		if (unit.equals("K")) distance = distance * 1.609344;
		if (unit.equals("N")) distance = distance * 0.8684;
		
		return distance;
	}
	

	
//  Brau
//	critica de campos de formulários de pesquisa
//
	
	public static boolean validaNumeroProcesso(String numeroProcesso) {
		boolean ok = true;
//			String [] arrayNumProc = numeroProcesso.split("-");
//			String numero = arrayNumProc[0];
//			String dv = arrayNumProc[1];
		if ( ! numeroProcesso.matches("\\d{5}.\\d{6}/(\\d{2}|\\d{4})-\\d{2}") ) {
			if ( ! numeroProcesso.matches("\\d{5}.\\d{6}/(\\d{2}|\\d{2})-\\d{2}") ) {
//				addMessage(ErrorMessage.NUMERO_PROCESSO_INVALIDO.getLabel());
				ok=false;
			}
		}
		return ok;
	}
	
	
	public static boolean validaNomeContribuinte(String nomeContribuinte) {
		boolean ok = true;
		if ( ! nomeContribuinte.matches("\\w{1,}\\s\\w{1,}.")) {
//			addMessage(ErrorMessage.NOME_CONTRIBUINTE_INVALIDO.getLabel());
			ok=false;
		}
		return ok;
	}


	public static boolean validaDataInicioFim(Date dataInicio, Date dataFim) {
		boolean ok = true;
		if ( ( dataInicio == null) && ( dataFim == null) ) {
//			addMessage(ErrorMessage.PERIODO_DATA_NAO_INFORMADO.getLabel());
			ok = false;
		}
		if ( ( dataInicio != null) && ( dataFim != null) ) {
			if (dataFim.before(dataInicio)){
//				addMessage(ErrorMessage.DATA_FINAL_MENOR_INICIAL.getLabel());
				ok = false;
			} 
		}
	return ok;
}

	public static boolean validaTelefone(String fone) {
		boolean ok = true;
		if ( fone.matches("(\\d{2})\\d{4}-\\d{4}") ) {
			if ( fone.length() > 10 ) {
//				addMessage(ErrorMessage.telefoneInvalido.getLabel());
				ok=false;
			}
		} else if ( fone.length() < 8 ) {
//			addMessage(ErrorMessage.telefoneInvalido.getLabel());
			ok=false;
		}
		return ok;
	}

//	
//	
//	
	
	
	public static String onlyNumber(String num) {
		String onlyNumber = "";
		Character c;
		for ( int i = 0; i < num.length(); i++) {
			c = num.charAt(i);
			if ( Character.isDigit(c)) onlyNumber += c;
		}
		return onlyNumber;
	}

	
   public static String mask(double value , String pattern) {
      DecimalFormat myFormatter = new DecimalFormat(pattern);
      String output = myFormatter.format(value);
      return output;
   }


   public static String mask(String numero, String mascara){
		if (numero == null) numero = "0";
		String num  = onlyNumber(numero);
		char n;
		String mask = num;
		int in = num.length()-1;
		if (mascara != null ) {
			mask = "";
			for ( int im = (mascara.length()-1); im > -1 ; im-- ) {
				char m = mascara.charAt(im);
				if (in >= 0 ) {
					n = num.charAt(in);
					if ( m == '9' || m =='#') {
							mask = n + mask;
							in--;
					} else {
							mask = m + mask;
					}
				} else {
					switch( m ) {
						case '9':
							mask = '0' + mask;
							break;
							// falta dar mais tratamento nesta opção.
						case '#':
							mask = ' ' + mask;
							break;
						default:
							mask = m + mask;
					}
				}
			}
		}
		return mask.replace(" .", "  ");
	}
	
	public static String formataData(Date data, String formato){
		if (data == null) return null;
		if (formato == null) formato = "dd/MM/yyy";
	    SimpleDateFormat formatter = null;		
	    try {
			formatter = new SimpleDateFormat(formato);
		} catch (RuntimeException e) {			
			e.printStackTrace();
		}        
		return formatter.format(data);
	}
	
	public static Date isStringDate(String dataString){		
		try{
			if (dataString!=null){
				if (dataString.equals("")){
					return null;
				}else{
					String[] data = dataString.split("/");   
					String dia = data[0];   
					String mes = data[1];   
					String ano = data[2];
					Calendar calendario = new GregorianCalendar();		
					calendario.set((new Integer(ano)).intValue(), (new Integer(mes)).intValue(), (new Integer(dia)).intValue());
					return calendario.getTime();
				}
			}else{
				return null;
			}			
		}catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static String retornaMesExtenso(String mes){
		if (mes.equals("01")){
			return "Janeiro";
		}else if (mes.equals("02")){
			return "Fevereiro";
		}else if (mes.equals("03")){
			return "Março";
		}else if (mes.equals("04")){
			return "Abril";
		}else if (mes.equals("05")){
			return "Maio";
		}else if (mes.equals("06")){
			return "Junho";
		}else if (mes.equals("07")){
			return "Julho";
		}else if (mes.equals("08")){
			return "Agosto";
		}else if (mes.equals("09")){
			return "Setembro";
		}else if (mes.equals("10")){
			return "Outubro";
		}else if (mes.equals("11")){
			return "Novembro";
		}else if (mes.equals("12")){
			return "Dezembro";
		}else{
			return "????";
		}
	}
	
	
	public static int retornaAno(Date data){
		if (data == null){
			return 0;
		}else{
			String dt = Utilitarios.formataData(data, "yyyy");
			return Integer.parseInt(dt);
		}
	}

	public static String formatarIp(String ipTerminal) {
        String [] ips = ipTerminal.split("\\.");
        ipTerminal = "";
        for (int i = 0; i < ips.length; i++) {
        	String ipParte = "000" + ips[i];
        	ipTerminal += ipParte.substring( ipParte.length() - 3, ipParte.length() );
		}
        return ipTerminal;
	}
	
	public static boolean validaNumInt(Integer num, String idCampo) {
		Boolean ok = true;
		if (num != null && onlyNumber(num.toString()) != "") {
			if (!Utilitarios.validaCampoSemCaracEspeciais(num.toString())) {
//				addMessage(idCampo, ErrorMessage.CARACTERES_INVALIDOS.getLabel());
				ok = false;
			} else {
				num = Integer.parseInt(onlyNumber(num.toString()));
			}
		}
		return ok;
	}

	public static boolean validaNumIntObrigatorioComZero(Integer num, String idCampo) {
		Boolean ok = true;
		if (num == null || onlyNumber(num.toString()) == "" ) {
//			addMessage(idCampo, ErrorMessage.PREENCHIMENTO_OBRIGATORIO.getLabel());
			ok = false;
		} else {
			if (!Utilitarios.validaCampoSemCaracEspeciais(num.toString())) {
//				addMessage(idCampo, ErrorMessage.CARACTERES_INVALIDOS.getLabel());
				ok = false;
			} else {
				if (num < 0) {
//					addMessage(idCampo,ErrorMessage.SOMENTE_NUMEROS_INTEIROS_POSITIVOS.getLabel());
					ok = false;
				} else {
					num = Integer.parseInt(onlyNumber(num.toString()));
				}
			}
		}
		return ok;
	}

	public static boolean validaNumIntObrigatorio(Integer num, String idCampo) {
		Boolean ok = true;
		if (num == null || onlyNumber(num.toString()) == "" || num == 0) {
//			addMessage(idCampo, ErrorMessage.PREENCHIMENTO_OBRIGATORIO.getLabel());
			ok = false;
		} else {
			if (!Utilitarios.validaCampoSemCaracEspeciais(num.toString())) {
//				addMessage(idCampo, ErrorMessage.CARACTERES_INVALIDOS.getLabel());
				ok = false;
			} else {
				if (num <= 0) {
//					addMessage(idCampo,ErrorMessage.SOMENTE_NUMEROS_INTEIROS_POSITIVOS.getLabel());
					ok = false;
				} else {
					num = Integer.parseInt(onlyNumber(num.toString()));
				}
			}
		}
		return ok;
	}

	public static boolean validaStr(String campo, String idCampo) {
		Boolean ok = true;
		if (campo != null && campo.trim() != "") {
			if (!Utilitarios.validaCampoSemCaracEspeciais(campo)) {
//				addMessage(idCampo, ErrorMessage.CARACTERES_INVALIDOS.getLabel());
				ok = false;
			} else {
				campo = campo.trim();
			}
		}
		return ok;
	}

	public static boolean validaStrObrigatorio(String campo, String idCampo) {
		Boolean ok = true;
		if (campo == null || campo.trim() == "") {
//			addMessage(idCampo, ErrorMessage.PREENCHIMENTO_OBRIGATORIO.getLabel());
			ok = false;
		} else {
			if (!Utilitarios.validaCampoSemCaracEspeciais(campo)) {
//				addMessage(idCampo, ErrorMessage.CARACTERES_INVALIDOS.getLabel());
				ok = false;
			} else {
				campo = campo.trim();
			}
		}
		return ok;
	}

	public static boolean validaCampoSemCaracEspeciais(String campo) {
		if (campo.contains("'") || campo.contains("\"") || campo.contains("\\")
				|| campo.contains("<") || campo.contains(">")
				|| campo.contains("{") || campo.contains("{")
				|| campo.contains("}") || campo.contains("[")
				|| campo.contains("]") || campo.contains("*")
				|| campo.startsWith("?") || campo.startsWith("&")
				|| campo.startsWith("~"))
			return false;
		return true;
	}

	public static boolean validaDataInicioFim(Date dataInicio, Date dataFim, String idCampo) {
		boolean ok = true;
		if ((dataInicio == null) && (dataFim == null)) {
			if (idCampo.equals("")) {
//				addMessage(ErrorMessage.PERIODO_DATA_NAO_INFORMADO.getLabel());
			}
			else {
//				addMessage(idCampo,ErrorMessage.PERIODO_DATA_NAO_INFORMADO.getLabel());
			}
			ok = false;
		}
		
		if ((dataInicio != null) && (dataFim != null)) {
			if (dataFim.before(dataInicio)) {
				if (idCampo.equals("")) {
//					addMessage(ErrorMessage.DATA_FINAL_MENOR_INICIAL.getLabel());
				}
				else{
//					addMessage(idCampo,ErrorMessage.DATA_FINAL_MENOR_INICIAL.getLabel());
				}
				ok = false;
			}
		}
		
		//Por Márcia Cristina Monteiro Em 14/07/2010
		if ( ( dataInicio != null && dataFim == null)||( dataInicio == null && dataFim != null) ) {
				if (idCampo.equals("")) {
//					addMessage(ErrorMessage.DATA_PERIODO_NAO_INFORMADA.getLabel());
				}
				else{
//					addMessage(idCampo,ErrorMessage.DATA_PERIODO_NAO_INFORMADA.getLabel());
				}
				ok = false;
		}
		return ok;
	}


	public static boolean validaTermoTransferencia(String termoTransf) {
		boolean ok = true;
		termoTransf = termoTransf.substring(5, 9);
	    int numTermoAno =  Integer.parseInt(termoTransf) ;
	    Date d = new Date();
	    Calendar c = Calendar.getInstance();
	    c.setTime(d);
	    int ano = c.get(Calendar.YEAR);
	    if (numTermoAno  > ano ){
	    	ok = false;	    
	    }
		return ok;
	}



	public static Long diferencaEmDias(Date data1, Date data2) {

		long dt = (data2.getTime() - data1.getTime()) + 3600000;
		long dias = (dt / 86400000L);

		return Math.abs(dias);
	}

	public static Date getDataCorrente() {
		return Calendar.getInstance().getTime();
	}

	public static Boolean isNumeric(String s) {
		// retirar caracteres de edição padrao(caso tenha) antes de chamar este
		// metodo
		if (s == null || s.length() == 0) {
			return false;
		}
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!Character.isDigit(c)) {
				return false;
			}
		}
		return true;
	}

	public static BigDecimal converteStringtoBigdecimal(String str) {
		if (str == null) {
			return null;
		}
		String valor1 = str.replace(".", "");
		String valor2 = valor1.replace(",", ".");
		return new BigDecimal(valor2);
	}

	public static String converteBigdecimaltoString(BigDecimal big) {
		if (big == null) {
			return null;
		}
		String pattern = "##,###,###,###,###,##0.00";

		Locale locale = new Locale("pt", "BR");

		DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
		symbols.setDecimalSeparator(',');
		symbols.setGroupingSeparator('.');
		DecimalFormat f = new DecimalFormat(pattern, symbols);
		return f.format(big);
	}

	public static void classificarSelecItemPorLabel(List<SelectItem> lista) {
		Collections.sort(lista, new Comparator<SelectItem>() {
			public int compare(SelectItem o1, SelectItem o2) {
				return o1.getLabel().compareToIgnoreCase(o2.getLabel());
			}
		});
	}

	public static Integer retornaDia(Date data) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(data);
		return cal.get(Calendar.DAY_OF_MONTH);
	}

	public static Integer retornaMes(Date data) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(data);
		return cal.get(Calendar.MONTH) + 1;
	}

	public static Integer toAnoMes (Date data) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(data);
		return cal.get(Calendar.YEAR) * 100 + cal.get(Calendar.MONTH) + 1;
	}


	public static String retornaSemana(Date data) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(data);
		return cal.get(Calendar.DAY_OF_MONTH) + "ª Semana";
	}

	public static String retornaDecendio(Date data) {
		int divisaoInteira = retornaDia(data) / 10;
		int Decendio = divisaoInteira + 1;
		return Decendio + "º Decêndio";
	}

	public static String retornaQuinzena(Date data) {
		if (retornaDia(data) <= 15) {
			return "1ª Quinzena";
		} else {
			return "2ª Quinzena";
		}
	}

	public static String retornaTrimestre(Date data) {
		if (retornaMes(data) <= 3) {
			return "1º Trimestre";
		} else if (retornaMes(data) > 3 || retornaMes(data) <= 6) {
			return "2º Trimestre";
		} else if (retornaMes(data) > 6 || retornaMes(data) <= 9) {
			return "3º Trimestre";
		} else {
			return "4º Trimestre";
		}
	}

	public static String preencheZerosEsquerda(String valor, int qtdTotal) {

		return String.format("%0" + qtdTotal + "d", Long.parseLong(valor));
	}

	public static String implode(String[] ary, String delim) {
		String out = "";
		for (int i = 0; i < ary.length; i++) {
			if (i != 0) {
				out += delim;
			}
			out += ary[i];
		}
		return out;
	}

	public static String soNumeros(String numeroEditado) {
		String soNumeros = "";
		char elemento;
		if (numeroEditado != null) {
			for (int j = 0; j <= (numeroEditado.length() - 1); j++) {
				elemento = numeroEditado.charAt(j);
				if ("1234567890".indexOf(elemento) >= 0) {
					soNumeros = soNumeros + elemento;
				}
			}
		}
		return soNumeros;
	}

/**
 *  Rotina para tratamento de excecoes do banco	
 * @param e
 * @return String com codigo do erro ou -1 se erro não previsto
 */
	public static String dbException( Exception e) {
		if ( e.getCause() instanceof ConstraintViolationException ) {
			ConstraintViolationException c = (ConstraintViolationException) e.getCause();
			if ( c.getCause() instanceof BatchUpdateException ) {
				BatchUpdateException b = (BatchUpdateException) c.getCause();
				return b.getNextException().getSQLState();
			}
		}
	return "99999";
}
	
   //rotina que separa em vírgulas os itens de uma lista de strings, removendo também elementos repetidos.
   //Exibe o formato ('a','b'). Caso um ")" ou "(" seja passado no parametro tipoLista. Ideal para o IN de consultas a banco de dados.
   //Exibe o formato a,b .caso no parametro tipoLista seja passado o valor null ou "".	
  // Por Márcia Cristina Monteiro	
	public static String formataItensListaString( List<String> lista, String tipoLista){
	    String itens = "";
	    
	    if ( tipoLista.equals("(")|| tipoLista.equals(")") ) {
	    		    	
	    	if (lista.size() > 0 ){
	    		
	    		for (String str : lista) {
				  	   if ( itens.indexOf(str) < 0 ) itens += "'" + str + "', ";  
				}
	    		
	    		itens =  "(" + itens.substring(0, itens.length() - 2) + ")"; 
	    	}
	    	else itens = "('')";
	    }
	    else{
	    	    	
	    	if (lista.size() > 0 ){
		    	for (String str : lista) {
				  	   if ( itens.indexOf(str) < 0 )  itens +=  str + ", ";  
				}
	    	
		    	itens = itens.substring(0, itens.length() - 2); 
	    	}	
	    }
	    	
	    return itens;

	}
	
	// função que preenche uma string com um determinado caracter à direita ou à esquerda ou em ambos até atingir o tamanho desejado
	//str = string a ser formatada, chr = caracter que irá formatar a string, tam = tamanho desejado com a formatação e 
	//ori = orientação. Coloque "D" para direita , "E" para esquerda ou "DE" ou "ED" para direita e esquerda
	//Por Márcia Cristina Monteiro Em 30/07/2010
	public static String preencheComCaracter(String str, String chr, Integer tam, String ori){
		String strAux = str;
		
		if ( chr.equals("") || chr == null )
			   return strAux;
		
		if ( ori.equalsIgnoreCase("D") ){
				while ( strAux.length() < tam ){
					strAux = strAux + chr;
				}
				return strAux;
		}
		else
		if ( ori.equalsIgnoreCase("E")){
				while ( strAux.length() < tam ){
					strAux = chr + strAux ;
				}
				return strAux;
		}
		else
		if (  ori.equalsIgnoreCase("DE")|| ori.equalsIgnoreCase("ED")){	
				int limE = 0;
				int limD = 0;
				
				if ( (tam - strAux.length())% 2 == 0 ){//divide por dois e se o resto for zero é porque é par, qtd iguais para direita e esquerda 
					limE = limD = (tam - strAux.length())/ 2 ;
				}
				else{// se for impar, tira 1 do tamanho pra dividir um  número par
					limE = ( (tam -1)- strAux.length())/2;
					limD = limE + 1;//acrescenta 1 no limite direito para compensar o 1 que se tirou por causa da divisão acima
				}
				
				for (int i = 1; i<=limE; i++){
					strAux = chr + strAux;
				}
				
				for (int i = 1; i <=limD; i++){
					strAux = strAux + chr;
				}
				return strAux;
		}
		
		return strAux;
		
	}

	

}
